Upload File using Model Validation in ASP.NET MVC
To achieve this you have to do the following steps:
Create Student class and add the following properties with some data annotation attributes :
public class Student
{
public int Id { get; set; }
[Required(ErrorMessage = "Please enter your first name!")]
[StringLength(25)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your last name!")]
[StringLength(25)]
public string LastName { get; set; }
[Required(ErrorMessage = "Please browse your image")]
[Display(Name = "Upload Image")]
[NotMapped]
[ValidateFile]
public HttpPostedFileBase Photo { get; set; }
}
Create a StudentDbContext class that inherits DbContext to setup table in a database:
public class StudentDbContext : DbContext
{
public DbSet<Student> Student { get; set; }
}
Create a class ValidateFileAttribute, inherits ValidationAttribute for data annotation validator for uploading file at server side:
//Customized data annotation validator for uploading file
public class ValidateFileAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
int maxContent = 1024 * 1024; //1 MB
string[] sAllowedExt = new string[] { ".jpg", ".gif", ".png" };
var file = value as HttpPostedFileBase;
if (file == null)
return false;
else if (!sAllowedExt.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
{
ErrorMessage = "Please upload Your Photo of type: " + string.Join(", ", sAllowedExt);
return false;
}
else if (file.ContentLength > maxContent)
{
ErrorMessage = "Your Photo is too large, maximum allowed size is : " + (maxContent / 1024).ToString() + "MB";
return false;
}
else
return true;
}
}
Add a connectionString element under the configuration tag in web.config, to setup database and information of students:
<connectionStrings>
<addname="StudentDbContext"connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=Student; Integrated Security=true"providerName="System.Data.SqlClient"/>
</connectionStrings>
Design Controller (HomeController) as given below:
public class HomeController : Controller
{
StudentDbContext db = new StudentDbContext();
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Student model)
{
//Check server side validation using data annotation
if (ModelState.IsValid)
{
try
{
db.Student.Add(model);
db.SaveChanges();
var extension = Path.GetExtension(model.Photo.FileName);
var path = Path.Combine(Server.MapPath("~/Content/Student/Photo/"));
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
model.Photo.SaveAs(path + model.Id + extension);
ModelState.Clear();
}
catch { }
return View();
}
else
return View(model);
}
}
Design View (Index) based on the model and write a script to validate file at client side:
@model UploadFile_ModelValidation.Models.Student
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script type="text/jscript">
//get file size
function GetFileSize(fileid) {
try {
var fileSize = 0;
//for IE
if ($.browser.msie) {
//before making an object of ActiveXObject,
//please make sure ActiveX is enabled in your IE browser
var objFSO = new ActiveXObject("Scripting.FileSystemObject"); var filePath = $("#" + fileid)[0].value;
var objFile = objFSO.getFile(filePath);
var fileSize = objFile.size; //size in kb
fileSize = fileSize / 1048576; //size in mb
}
//for FF, Safari, Opeara and Others
else {
fileSize = $("#" + fileid)[0].files[0].size //size in kb
fileSize = fileSize / 1048576; //size in mb
}
return fileSize;
}
catch (e) {
alert("Error is :" + e);
}
}
//get file path from client system
function getNameFromPath(strFilepath) {
var objRE = new RegExp(/([^\/\\]+)$/);
var strName = objRE.exec(strFilepath);
if (strName == null) {
return null;
}
else {
return strName[0];
}
}
$(function () {
$("#Photo").change(function () {
var file = getNameFromPath($(this).val());
if (file != null) {
var extension = file.substr((file.lastIndexOf('.') + 1));
switch (extension) {
case 'jpg':
case 'png':
case 'gif':
flag = true;
break;
default:
flag = false;
}
}
if (flag == false) {
$("#validationTxt").text("You can upload only jpg,png,gif extension file");
return false;
}
else {
var size = GetFileSize('file');
if (size > 3) {
$("#validationTxt").text("You can upload file up to 1 MB");
}
else {
$("#validationTxt").text("");
}
}
});
});
</script>
</head>
<body>
<div>
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table cellpadding="5">
<tr>
<td>
@Html.LabelFor(m => m.FirstName)
</td>
<td>
@Html.TextBoxFor(m => m.FirstName, new { maxlength = 25 })
@Html.ValidationMessageFor(m => m.FirstName)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.LastName)
</td>
<td>
@Html.TextBoxFor(m => m.LastName, new { maxlength = 25 })
@Html.ValidationMessageFor(m => m.LastName)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(m => m.Photo)
</td>
<td>
@Html.TextBoxFor(m => m.Photo, new { type = "file" })
@Html.ValidationMessageFor(m => m.Photo, string.Empty, new { id = "validationTxt" })
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
}
</div>
</body>
</html>
When you run an application and directly press the Submit button, it will look something like below:
Enter student information and browse photos to save student data.
After saving you can verify, the image has been successfully uploaded on the server. It will create a folder if the folder does not exist.
Thanks for reading this article. I think this will help you a lot.
Ravi Anand
14-Apr-2016//css part
//.cshtml part
//jquery part
Atik Shaikh
06-Apr-2016